$:.unshift File.join(File.dirname(__FILE__))
require 'utils'

#represents a dcop amarok call to whatever object is given as prefix
class Amarok
  def initialize prefix
    @prefix = prefix
  end
  def method_missing name, *args
    method_name = name.to_s.gsub(/_\w/) {|match| 
      match[-1..-1].upcase
    }

    argString = ""
    args.each {|arg| argString += " '#{arg}'"}

    cmd = "dcop amarok #{@prefix} #{method_name} #{argString}"

    response = `#{cmd}`
    response.chomp! if !response.nil?
    return response
  end
end

class PlaylistItem
  attr_accessor :artist, :kurl
  def to_s
    "#{@artist || 'no artist'}-#{@kurl || 'no url'}"
  end
end

#parses the playlist xml to PlaylistItem objects
def retrieve_playlist_items doc
  playlist_items = []
  doc.elements.each('playlist/item'){|elem|
    item = PlaylistItem.new
    item.artist = elem.elements["Artist"].children[0].to_s
    item.kurl = elem.attributes["url"]
    playlist_items << item
  }
  playlist_items
end

def smart_shuffle playlist
  playlist.shuffle!
  groups = playlist.group_by {|item| item.artist}

  groups.inject([]) {|decorated_playlist, group|
    decorated_playlist + group.decorate {|item, index|
      every_n = playlist.length.to_f / group.length.to_f
      rank = every_n * (index + 1) - (every_n / 2.to_f)
    }
  }.sort_by_decoration.undecorate
end
